package cn.cloud.jianghai.userservice.service.impl;

import cn.cloud.jianghai.jianghaicommon.entity.R;
import cn.cloud.jianghai.jianghaicommon.utils.ConvertUtil;
import cn.cloud.jianghai.jianghaicommon.utils.ExceptionUtil;
import cn.cloud.jianghai.orderapi.entity.OrderDto;
import cn.cloud.jianghai.orderapi.feign.OrderApi;
import cn.cloud.jianghai.userapi.dto.UserDto.UserDto;
import cn.cloud.jianghai.userservice.domain.User;
import cn.cloud.jianghai.userservice.mapper.UserMapper;
import cn.cloud.jianghai.userservice.query.UserQuery;
import cn.cloud.jianghai.userservice.service.UserService;
import cn.cloud.jianghai.userservice.vo.UserVo;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author jianghai
 * @description 针对表【t_user】的数据库操作Service实现
 * @createDate 2022-05-22 16:54:29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    private final OrderApi orderApi;

    private final RocketMQTemplate rocketMQTemplate;

    @Override
    public List<UserVo> findUserList(UserQuery query) {

        LambdaQueryWrapper<User> lambdaQuery = getCondition(query);

        List<User> userList = list(lambdaQuery);

        if (CollectionUtil.isEmpty(userList)) {
            return Lists.newArrayList();
        }

        List<Long> userIdList = userList.stream()
                .map(User::getId)
                .collect(Collectors.toList());

        R<List<OrderDto>> r = orderApi.findOrderList(userIdList);

        List<OrderDto> orderDtoList = null;
        ExceptionUtil.businessException(!r.getStatus() || CollectionUtil.isEmpty(orderDtoList = r.getData()),
                "调用订单服务异常, 请稍后再试");

        Map<Long, List<OrderDto>> userIdOrderListMap = orderDtoList.stream()
                .collect(Collectors.groupingBy(OrderDto::getUserId));

        List<UserVo> userVoList = ConvertUtil.copyListProperties(userList, UserVo.class);

        userVoList.forEach(item -> item.setOrderDtoList(userIdOrderListMap.get(item.getId())));

        return userVoList;
    }


    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public Boolean insert(UserDto userDto) {


        User user = ConvertUtil.copyBeanProperties(userDto, User.class);
        boolean flag = save(user);

        OrderDto orderDto = new OrderDto();
        orderDto.setId(IdWorker.getId());
        orderDto.setNo("u-1002");
        orderDto.setGmtOrder(new Date());
        orderDto.setUserId(user.getId());
        orderDto.setGmtCreate(new Date());
        orderDto.setGmtModify(new Date());
        orderDto.setStatus(0);

        R<Boolean> r = orderApi.insertOrder(orderDto);
        ExceptionUtil.businessException((!r.getStatus() || !r.getData()), r.getMsg());

        if (flag) {
            // 异步发送
            rocketMQTemplate.asyncSend("user-service-topic:tag1", userDto, new SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    log.info("消息发送成功, {}", JSON.toJSONString(sendResult));
                }

                @Override
                public void onException(Throwable throwable) {
                    log.info("消息发送失败, {}", JSON.toJSONString(throwable));
                }
            });
            // 同步发送
            SendResult result = rocketMQTemplate.syncSend("user-service-topic:tag1", userDto);
            return result.getSendStatus() == SendStatus.SEND_OK;
        }

        return Boolean.FALSE;
    }

    private LambdaQueryWrapper<User> getCondition(UserQuery query) {

        if (Objects.isNull(query)) {
            return new LambdaQueryWrapper<>();
        }

        return new LambdaQueryWrapper<>();
    }

    @Override
    public List<OrderDto> testHystrix(Long id) {

        R<List<OrderDto>> r = orderApi.testHystrix(id);

        return r.getData();
    }

    public static void main(String[] args) {
        int a = 1;
        int b = 2;

        a = a + b;
        b = a - b;
        a = a - b;
        System.out.println("a : " + a + ", b : " + b);

        int[] arr = {1,5,6,1,4,5,6};

        System.out.println(sum(arr, 0));
    }

    private static int sum(int[] arr, int idx) {


        return arr.length == idx ? 0 : arr[idx] + sum(arr, idx + 1);
    }
}




